2 - 非同步之Promise串 API


Posted by backas36 on 2021-07-21

這是 Fetch, Promise, Async & Await 的 第二篇,有興趣的朋友可以先看 非同步之認識Promise。

上一篇有簡單介紹 Promise 之後,我們可以使用 Promise 來串 API 試試看,API URL 一樣是使用上一篇的網址,如果有過期問題記得提醒我,謝謝!

Promise 串 API

先來長長的範例如下:

const api200 = 'https://run.mocky.io/v3/98c6ea3a-2359-429d-8be1-98396934af0f'
// 完全正常運作的 server

const api500 = 'https://run.mocky.io/v3/bf2b926c-0db4-4f98-b09a-1211d4da6038'
// 假裝 server error 回傳 500 的 api

const apiJsonError = 'https://run.mocky.io/v3/3bf6bbd8-6b7c-47f7-8b92-9efb2a0a8dfc'
// 回傳 200 但是 json 格式錯誤的 api

const apiWrongUrl = 'https://srun.mocky.io/v3/98c6ea3a-2359-429d-8be1-98396934af0f'




// 新建 promise
const requestPromise = new Promise((resolve, reject) => {
  var request = new XMLHttpRequest();
  request.open('GET', api200, true);

  request.onload = function () {
    if (this.status >= 200 && this.status < 400) {
      let data
      try {
        data = JSON.parse(this.response)
      } catch (error) {
        reject(error) // apiJsonError 的結果
        return
      }
      resolve(data) // api200的結果

    } else {
      reject(request.statusText)
      // api500 的結果 : Internal Server Error
      return
    }
  };

  request.onerror = function () {
    reject('request 有錯囉')
    //apiWrongUrl的結果
    return
  }

  request.send();
})
  .then(data => {
    console.log(data)
  })
  .catch(error => {
    console.log(error)
  })

此範例變數使用 api200 ,所以會成功執行 resolve(data),我們可以直接在後面接上 then 來接收 API 回傳的 data,也可以不用再後面直接加上去另外拆開寫成這樣也是可以

requestPromise.then(data => {
  console.log(data)
})
  .catch(error => {
    console.log(error)
  })

如果帶入其他三個錯誤的 API 變數的話,都會 reject,我們 then 的後面加上 catch,就可以接收 reject 傳過來的錯誤訊息。

你可能會想,那這樣有什麼好處呢? 有,我們可以利用 Promise 的語法來一直串 API,我們改寫一下 requestPromise 是可以接收參數,接著我們就可以利用這個參數,來串很多次的 API。

新增到範例用的API網站

先新增一個變數來放 API URL,並且改寫一下 requestPromise

 const api200 = 'https://run.mocky.io/v3/98c6ea3a-2359-429d-8be1-98396934af0f'
// 完全正常運作的 server

const api500 = 'https://run.mocky.io/v3/bf2b926c-0db4-4f98-b09a-1211d4da6038'
// 假裝 server error 回傳 500 的 api

const apiJsonError = 'https://run.mocky.io/v3/3bf6bbd8-6b7c-47f7-8b92-9efb2a0a8dfc'
// 回傳 200 但是 json 格式錯誤的 api

const apiWrongUrl = 'https://srun.mocky.io/v3/98c6ea3a-2359-429d-8be1-98396934af0f'

const apiUser = 'https://reqres.in/api/users'


// 新建 promise
const requestPromise = (apiURL) => {
  return new Promise((resolve, reject) => {
    var request = new XMLHttpRequest();
    request.open('GET', apiURL, true);

    // ... 以下與上個範例一樣
}

requestPromise(api200).then(data => {
  console.log(data)
  return requestPromise(apiUser)
}).then(userData => {
  console.log(userData)
})
  .catch(error => {
    console.log(error)
  })

可以看到我們可以利用 return 回傳一個 Promise ,接著就可以繼續 then 來串 API 剛剛加入的 API,非同步測試的 console.log ,就不示範了,可以自己 console 試試看。

以上介紹完簡單的 Promise 以及利用 Promise 來串 API 後,我們可以知道 Promise 可以讓我們做到非同步來執行程式,但其實我們還有更方便的 fetch 可以用。

來,再一篇。
1 - 非同步之認識Promise
2 - 非同步之Promise串 API
3 - 非同步之認識 fetch
4 - 非同步之認識 async/await


#非同步 #javascript #Promise







Related Posts

使用 Python 進行中斷點 step by step debug 除錯

使用 Python 進行中斷點 step by step debug 除錯

Covariance and Contravariance in Generics

Covariance and Contravariance in Generics

enum

enum


Comments